#include "ClientWindow.h"

// Public Methods


/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::ClientWindow (QWidget * parent) : QMainWindow(parent)
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	RETURNS:		string - filename of song
--
--	NOTES:
--                  Constructor for the ClientWindow
---------------------------------------------------------------------------------------*/
ClientWindow::ClientWindow (QWidget * parent) : QMainWindow(parent)
{
    GlobalError::initInstance();

    playlistClient = new PlaylistClient();
    multicastClient = new MulticastClient();

    playlistClient->addObserver(this);

    setWindowTitle("SocialRadio - Client");
    setCentralWidget(new QWidget());
    resize(400, 400);

    initMenu();
    initMainLayout();
    updateGUI();
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::notify (Observable * obj, int eventCode)
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	RETURNS:		string - filename of song
--
--	NOTES:
--                  Function to notify the client window
---------------------------------------------------------------------------------------*/
void ClientWindow::notify (Observable * obj, int eventCode)
{
    if (obj == playlistClient)
    {
        QMetaObject::invokeMethod(this, "handleUpload", Qt::QueuedConnection, Q_ARG(int, eventCode));
    }
}

// Slots

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::connect ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to connet to the server
---------------------------------------------------------------------------------------*/
void ClientWindow::connect ()
{
    QString ipAddress = QInputDialog::getText(this, "Server IP Address", "Please enter the server's IP address");

    playlistClient->connectToServer(ipAddress.toStdString(), 4998);
    multicastClient->receiveFromStream(false);
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::disconnect ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to disconnet from the server
---------------------------------------------------------------------------------------*/
void ClientWindow::disconnect ()
{
	playlistClient->close();
	multicastClient->close();
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::recordAndUpload ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to send the record file to the server
---------------------------------------------------------------------------------------*/
void ClientWindow::recordAndUpload ()
{
    // @todo
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::chooseFileAndUpload ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function for the user to choose file and upload
---------------------------------------------------------------------------------------*/
void ClientWindow::chooseFileAndUpload ()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Choose audio file to upload"),
                                                    "~",
                                                    tr("Audio (*.wav)"));

    if (fileName.size() > 1)
    {
        fileName.replace(QString("/"), QString("\\"));
        playlistClient->sendFile(fileName.toStdString());
    }
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::handleUpload (int eventCode)
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function for the user to choose file and upload
---------------------------------------------------------------------------------------*/
void ClientWindow::handleUpload (int eventCode)
{
    int value = 0;

    switch (eventCode)
    {
    case PlaylistClient::UploadStarted:
        uploadStatus = new QProgressDialog("Uploading...", "", 0, 100, this);
        uploadStatus->setCancelButton(0);
        uploadStatus->show();
        break;

    case PlaylistClient::UploadProgressChanged:
        value = (int) playlistClient->getUploadProgress();
        uploadStatus->setValue(value);
        break;

    case PlaylistClient::UploadFinished:
        uploadStatus->close();
        delete uploadStatus;
        break;
    }
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::play ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to play music
---------------------------------------------------------------------------------------*/
void ClientWindow::play ()
{
	multicastClient->start();
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::pause ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to pause music
---------------------------------------------------------------------------------------*/
void ClientWindow::pause ()
{
	multicastClient->getAudioSystem()->stop();
	multicastClient->stop();
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::stop ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to stop music
---------------------------------------------------------------------------------------*/
void ClientWindow::stop ()
{
	multicastClient->getAudioSystem()->stop();
	multicastClient->stop();
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::volumeChanged (int volume)
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		John Kuo
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to change the volume
---------------------------------------------------------------------------------------*/
void ClientWindow::volumeChanged (int volume)
{
    double ratio = (double) volume / 100;
    double actualVolume = ratio * 65535;
    multicastClient->getAudioSystem()->changeVolume((DWORD)actualVolume);
}

// Private Methods

/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::initMenu ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to initiate the client menu
---------------------------------------------------------------------------------------*/
void ClientWindow::initMenu ()
{
    QMenu * connectionMenu = menuBar()->addMenu("&Connection");

    QAction * connectAction = new QAction(tr("&Connect..."), this);
    connectionMenu->addAction(connectAction);

    QAction * disconnectAction = new QAction(tr("&Disconnect"), this);
    connectionMenu->addAction(disconnectAction);

    QMenu * uploadMenu = menuBar()->addMenu("&Upload");

    QAction * recordAction = new QAction(tr("&Record microphone..."), this);
    uploadMenu->addAction(recordAction);

    QAction * fileAction = new QAction(tr("&Send audio file..."), this);
    uploadMenu->addAction(fileAction);

    QObject::connect(connectAction, SIGNAL(triggered()), this, SLOT(connect()));
    QObject::connect(disconnectAction, SIGNAL(triggered()), this, SLOT(disconnect()));

    QObject::connect(recordAction, SIGNAL(triggered()), this, SLOT(recordAndUpload()));
    QObject::connect(fileAction, SIGNAL(triggered()), this, SLOT(chooseFileAndUpload()));
}


/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::updateMenu ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to update the client menu
---------------------------------------------------------------------------------------*/
void ClientWindow::updateMenu ()
{
}


/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::initMainLayout ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to initiate the main page layout
---------------------------------------------------------------------------------------*/
void ClientWindow::initMainLayout ()
{
    playbackBar = addToolBar("Playback");

    playAction = new QAction(style()->standardIcon(QStyle::SP_MediaPlay), tr("Play"), this);
    playbackBar->addAction(playAction);
	QObject::connect(playAction, SIGNAL(triggered()), this, SLOT(play()));

    pauseAction = new QAction(style()->standardIcon(QStyle::SP_MediaPause), tr("Pause"), this);
    playbackBar->addAction(pauseAction);
	QObject::connect(pauseAction, SIGNAL(triggered()), this, SLOT(pause()));

    stopAction = new QAction(style()->standardIcon(QStyle::SP_MediaStop), tr("Stop"), this);
    playbackBar->addAction(stopAction);
	QObject::connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));

    playbackBar->addSeparator();

    volumeSlider = new QSlider(Qt::Horizontal);
    volumeSlider->setRange(0, 100);
    playbackBar->addWidget(volumeSlider);
    QObject::connect(volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)));

    mainLayout = new QVBoxLayout();

    playlistWidget = new PlaylistWidget(playlistClient->getPlaylist(), playlistClient);
    playlistWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);

    mainLayout->addWidget(playlistWidget, Qt::AlignTop);

    mainLayout->addStretch();

    logo = new QPixmap();
    logo->load(":Resources/Images/socialradio.png", "PNG");
    imageLabel = new QLabel(0, this);
    imageLabel->setPixmap(*logo);
    mainLayout->addWidget(imageLabel, Qt::AlignHCenter);
}


/*---------------------------------------------------------------------------------------
--	FUNCTION:	ClientWindow::updateGUI ()
--
--	DATE:			March 22, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Rebeiro
--
--	PROGRAMMER:		Eric Rebeiro
--
--	NOTES:
--                  Function to update the GUI
---------------------------------------------------------------------------------------*/
void ClientWindow::updateGUI ()
{
    centralWidget()->setLayout(mainLayout);
}
